package org.noobie.photopicker.ui;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CompoundButton;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import org.noobie.photopicker.R;
import org.noobie.photopicker.common.Global;
import org.noobie.photopicker.domain.PhotoPickerDomain;
import org.noobie.photopicker.entity.Album;
import org.noobie.photopicker.entity.Photo;
import org.noobie.photopicker.listener.OnLocalAlbumListener;
import org.noobie.photopicker.listener.OnLocalRecentListener;
import org.noobie.photopicker.listener.OnPhotoItemCheckedListener;
import org.noobie.photopicker.util.AnimationUtil;
import org.noobie.photopicker.util.CommonUtils;

import java.util.ArrayList;
import java.util.List;

import me.yokeyword.fragmentation.SupportFragment;

public class PhotoPickerFragment extends SupportFragment implements
        OnItemClickListener, OnPhotoItemCheckedListener, org.noobie.photopicker.listener.OnItemClickListener,
        OnClickListener {

    public static String RECENT_PHOTO = null;
    /**
     * 相册的图片文件
     */
    private GridView gvPhotos;
    private PhotoSelectorAdapter photoAdapter;
    /**
     * 相册列表
     */
    private ListView lvAlbum;
    private AlbumAdapter albumAdapter;
    /**
     * 文件夹名称，
     */
    private TextView tvAlbum;
    /**
     * 预览按钮
     */
    private TextView tvPreview;
    /**
     * 标题
     */
    private TextView tvTitle;
    /***
     * 获取本地图库的控制器
     */
    private PhotoPickerDomain photoPickerDomain;
    /**
     * 已选中的文件列表
     */
    private ArrayList<Photo> selected;

    /**
     * 确定按钮
     */
    private TextView tvNumber;

    /**
     * 最近照片目录的更新
     */
    private OnLocalRecentListener recentListener = new OnLocalRecentListener() {
        @Override
        public void onPhotoLoaded(List<Photo> photos) {
            for (Photo model : photos) {
                if (selected.contains(model)) {
                    model.setChecked(true);
                }
            }
            photoAdapter.update(photos);
            // 滚动到顶端
            gvPhotos.smoothScrollToPosition(0);
            // reset(); //--keep selected photos
        }
    };

    /**
     * 更换查看相册
     */
    private OnLocalAlbumListener albumListener = new OnLocalAlbumListener() {
        @Override
        public void onAlbumLoaded(List<Album> albums) {
            albumAdapter.update(albums);
        }
    };

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.tv_right_lh || v.getId() == R.id.tv_number) {
            //确认按钮
            ok();
        } else if (v.getId() == R.id.tv_album_ar || v.getId() == R.id.tv_album_ar_layout) {
            //打开相册列表
            album();
        } else if (v.getId() == R.id.tv_preview_ar) {
            //预览按钮
            preview();
        } else if (v.getId() == R.id.tv_camera_vc) {
            //开启照相机，暂时未使用
//            catchPicture();
        } else if (v.getId() == R.id.tv_title_vb) {
            //返回按钮
            if (lvAlbum.getVisibility() == View.GONE) {
                pop();
            } else {
                hideAlbum();
            }

        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        return inflater.inflate(R.layout.activity_photoselector, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        RECENT_PHOTO = getResources().getString(R.string.recent_photos);
        if (getArguments() != null) {
            Global.Ref.MAX_IMAGE = getArguments().getInt(Global.Def.KEY_MAX, 1);
        } else {
            Global.Ref.MAX_IMAGE = 1;
        }

        tvTitle = view.findViewById(R.id.tv_title);
        gvPhotos = view.findViewById(R.id.gv_photos_ar);
        lvAlbum = view.findViewById(R.id.lv_ablum_ar);
//        tvOk = view.findViewById(R.id.tv_ok);

        tvAlbum = view.findViewById(R.id.tv_album_ar);
        tvPreview = view.findViewById(R.id.tv_preview_ar);
        tvNumber = view.findViewById(R.id.tv_number);

        // 返回
        view.findViewById(R.id.tv_title_vb).setOnClickListener(this);
        view.findViewById(R.id.tv_right_lh).setOnClickListener(this);
        view.findViewById(R.id.tv_album_ar_layout).setOnClickListener(this);
        tvNumber.setOnClickListener(this);
        tvAlbum.setOnClickListener(this);
        tvPreview.setOnClickListener(this);

        initData();
    }


    /**
     * 初始化数据
     */
    private void initData() {
        tvAlbum.setText(getString(R.string.recent_photos));
        tvTitle.setText(getString(R.string.recent_photos));
//        tvOk.setText(getString(R.string.select_complete, 0));

        photoPickerDomain = new PhotoPickerDomain(getContext().getApplicationContext());
        selected = new ArrayList<>();

        photoAdapter = new PhotoSelectorAdapter(this,
                new ArrayList<>(), CommonUtils.getWidthPixels(getActivity()),
                this, this, this);
        gvPhotos.setAdapter(photoAdapter);

        albumAdapter = new AlbumAdapter(getContext(),
                new ArrayList<>());
        lvAlbum.setAdapter(albumAdapter);
        lvAlbum.setOnItemClickListener(this);

        photoPickerDomain.getRecent(recentListener); // 更新最近照片
        photoPickerDomain.updateAlbum(albumListener); // 跟新相册信息
    }

    @Override
    public void onFragmentResult(int requestCode, int resultCode, Bundle data) {
        super.onFragmentResult(requestCode, resultCode, data);
        if (requestCode == Global.Def.REQUEST_CAMERA && resultCode == RESULT_OK) {
            Photo Photo = new Photo(CommonUtils.query(
                    getContext(), (Uri) data.get("uri")));
            //照相后的操做，暂时没有
            if (selected.size() >= Global.Ref.MAX_IMAGE) {
                Toast.makeText(getContext(), String.format(getString(R.string.max_img_limit_reached),
                        Global.Ref.MAX_IMAGE), Toast.LENGTH_SHORT).show();
                Photo.setChecked(false);
                photoAdapter.notifyDataSetChanged();
            } else {
                if (!selected.contains(Photo)) {
                    selected.add(Photo);
                }
            }
            ok();
        } else if (requestCode == PhotoPreviewFragment.REQUEST_CODE && resultCode == RESULT_OK) {
            if (data != null) {
                selected = data.getParcelableArrayList(Global.Def.KEY_SELECT);
                List<Photo> photos = photoAdapter.getItems();
                for (Photo model : photos) {
                    model.setChecked(selected.contains(model));
                }
                photoAdapter.notifyDataSetChanged();
                tvNumber.setText("(" + selected.size() + ")");
                if (selected.isEmpty()) {
                    tvPreview.setEnabled(false);
                    tvPreview.setTextColor(getResources().getColor(R.color.preview_gray));
                    tvPreview.setText(getString(R.string.preview));
                } else {
                    tvPreview.setEnabled(true);
                    tvPreview.setTextColor(getResources().getColor(R.color.bg));
                }
            }
        }
    }

    /**
     * 完成
     */
    private void ok() {
        if (selected.isEmpty()) {
            setFragmentResult(RESULT_CANCELED, null);
        } else {
            Bundle bundle = new Bundle();
            bundle.putParcelableArrayList("photos", selected);
            setFragmentResult(RESULT_OK, bundle);
        }
        pop();
    }

    /**
     * 弹出目录列表
     */
    private void album() {
        if (lvAlbum.getVisibility() == View.GONE) {
            popAlbum();
        } else {
            hideAlbum();
        }
    }

    /**
     * 拍照，暂时未使用
     */
    private void catchPicture() {
        CommonUtils.launchActivityForResult(getActivity(), new Intent(
                MediaStore.ACTION_IMAGE_CAPTURE), Global.Def.REQUEST_CAMERA);
    }

    /**
     * 弹出相册列表
     */
    private void popAlbum() {
        lvAlbum.setVisibility(View.VISIBLE);
        new AnimationUtil(getContext(), R.anim.translate_up_current)
                .setLinearInterpolator().startAnimation(lvAlbum);
    }

    /**
     * 隐藏相册列表
     */
    private void hideAlbum() {
        new AnimationUtil(getContext(), R.anim.translate_down)
                .setLinearInterpolator().startAnimation(lvAlbum);
        lvAlbum.setVisibility(View.GONE);
    }

    /**
     * 清空选中的图片
     */
    private void reset() {
        selected.clear();
        tvNumber.setText("(0)");
        tvPreview.setEnabled(false);
        tvPreview.setTextColor(getResources().getColor(R.color.preview_gray));
    }

    /**
     * 预览照片，查看当前选中的几张图片
     */
    private void preview() {
        Bundle bundle = new Bundle();
        bundle.putParcelableArrayList("photos", selected);

        PhotoPreviewFragment fragment = new PhotoPreviewFragment();
        fragment.setArguments(bundle);
        startForResult(fragment, PhotoPreviewFragment.REQUEST_CODE);
    }

    /**
     * 长按item，查看该目录下的全部图片
     * @param position 位置
     */
    @Override
    public void onItemLongClick(int position) {
        Bundle bundle = new Bundle();
        bundle.putInt("position", position);
        bundle.putParcelableArrayList("selected", selected);
        bundle.putString("album", tvAlbum.getText().toString());

        PhotoPreviewFragment fragment = new PhotoPreviewFragment();
        fragment.setArguments(bundle);
        startForResult(fragment, PhotoPreviewFragment.REQUEST_CODE);
    }


    /**
     * 是否已经选择达到了最大的可选数目
     *
     * @return
     */
    public boolean hasChoiceMaxSize() {
        return selected.size() >= Global.Ref.MAX_IMAGE;
    }

    /**
     * 点击显示图片的checkbox，选中状态发生变化时
     *
     * @param Photo
     * @param buttonView
     * @param isChecked
     */
    @Override
    public void onCheckedChanged(Photo Photo, CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            if (!selected.contains(Photo)) {
                selected.add(Photo);
            }
            tvPreview.setEnabled(true);
            tvPreview.setTextColor(getResources().getColor(R.color.bg));
        } else {
            selected.remove(Photo);
        }
        tvNumber.setText("(" + selected.size() + ")");

        if (selected.isEmpty()) {
            tvPreview.setEnabled(false);
            tvPreview.setTextColor(getResources().getColor(R.color.preview_gray));
            tvPreview.setText(getString(R.string.preview));
        }
    }


    /**
     * 相册列表的点击事件，
     *
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
        Album current = (Album) parent.getItemAtPosition(position);
        for (int i = 0; i < parent.getCount(); i++) {
            Album album = (Album) parent.getItemAtPosition(i);
            album.setChecked(i == position);
        }
        albumAdapter.notifyDataSetChanged();
        hideAlbum();
        tvAlbum.setText(current.getName());
        tvTitle.setText(current.getName());

        // 更新照片列表
        if (current.getName().equals(RECENT_PHOTO)) {
            photoPickerDomain.getRecent(recentListener);
        } else {
            // 获取选中相册的照片
            photoPickerDomain.getAlbum(current.getName(), recentListener);
        }

    }

    @Override
    public boolean onBackPressedSupport() {
        if (lvAlbum.getVisibility() == View.VISIBLE) {
            hideAlbum();
        } else {
            return false;
        }
        return true;
    }
}
